package com.ruoyi.school.service.impl;

import com.alibaba.excel.EasyExcel;
import com.ruoyi.school.domain.SchoolTdxDto;
import com.ruoyi.school.domain.TopVO;
import com.ruoyi.school.listener.TdxListener;
import com.ruoyi.school.runnables.ExcelInsertRunnable;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.school.mapper.SchoolTdxMapper;
import com.ruoyi.school.domain.SchoolTdx;
import com.ruoyi.school.service.ISchoolTdxService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 投档线Service业务层处理
 *
 * @author zyf
 * @date 2024-09-10
 */
@Service
public class SchoolTdxServiceImpl implements ISchoolTdxService {
    @Autowired
    private SchoolTdxMapper schoolTdxMapper;

    /**
     * 查询投档线
     *
     * @param id 投档线主键
     * @return 投档线
     */
    @Override
    public SchoolTdx selectSchoolTdxById(Long id) {
        return schoolTdxMapper.selectSchoolTdxById(id);
    }

    /**
     * 查询投档线列表
     *
     * @param schoolTdx 投档线
     * @return 投档线
     */
    @Override
    public List<SchoolTdx> selectSchoolTdxList(SchoolTdx schoolTdx) {
        return schoolTdxMapper.selectSchoolTdxList(schoolTdx);
    }

    /**
     * 新增投档线
     *
     * @param schoolTdx 投档线
     * @return 结果
     */
    @Override
    public int insertSchoolTdx(SchoolTdx schoolTdx) {
        return schoolTdxMapper.insertSchoolTdx(schoolTdx);
    }

    /**
     * 修改投档线
     *
     * @param schoolTdx 投档线
     * @return 结果
     */
    @Override
    public int updateSchoolTdx(SchoolTdx schoolTdx) {
        return schoolTdxMapper.updateSchoolTdx(schoolTdx);
    }

    /**
     * 批量删除投档线
     *
     * @param ids 需要删除的投档线主键
     * @return 结果
     */
    @Override
    public int deleteSchoolTdxByIds(Long[] ids) {
        return schoolTdxMapper.deleteSchoolTdxByIds(ids);
    }

    /**
     * 删除投档线信息
     *
     * @param id 投档线主键
     * @return 结果
     */
    @Override
    public int deleteSchoolTdxById(Long id) {
        return schoolTdxMapper.deleteSchoolTdxById(id);
    }

    /**
     * 录入导入的excel文件
     *
     * @param files 投档excel文件
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addExcel(List<MultipartFile> files) throws IOException {
        //开启线程池执
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
        for (MultipartFile file : files) {
            List<SchoolTdx> list = new ArrayList<>();
            InputStream inputStream = file.getInputStream();
            EasyExcel.read(inputStream, SchoolTdxDto.class, new TdxListener(list))
                    .build().readAll();
            //            开启线程池
//            若是list数据量太大则切分逐片插入
            if (list.size() >= 1000) {
                List<List<SchoolTdx>> lists = splitList(list, (list.size() / 1000) + 1);
                for (List<SchoolTdx> schoolTdxes : lists) {
                    scheduledExecutorService.execute(new ExcelInsertRunnable(schoolTdxes, schoolTdxMapper));
                }
            } else {
                scheduledExecutorService.execute(new ExcelInsertRunnable(list, schoolTdxMapper));
            }
            //        关闭线程池
            scheduledExecutorService.shutdown();
        }
    }

    /**
     * 热点学校top
     */
    @Override
    public List<TopVO> getSchoolTop() {
        return schoolTdxMapper.getSchoolTop();
    }
    /**
     * 热点专业top
     */
    @Override
    public List<TopVO> getSpecialityTop() {
        return schoolTdxMapper.getSpecialityTop();
    }

    @Override
    public List<String> getSchoolList() {
        return schoolTdxMapper.getSchoolList();
    }

    @Override
    public List<String> getSpecialityList(String schoolName) {
        return schoolTdxMapper.getSpecialityList(schoolName);
    }

    /**
     * 将一个列表分割成指定数量的部分。
     *
     * @param originalList  要分割的原始列表
     * @param numberOfParts 分割后的部分数量
     * @return 包含分割后子列表的列表
     */
    public static <T> List<List<T>> splitList(List<T> originalList, int numberOfParts) {
        if (numberOfParts <= 0) {
            throw new IllegalArgumentException("numberOfParts must be positive");
        }

        List<List<T>> subLists = new ArrayList<>();
        int totalSize = originalList.size();
        int chunkSize = (int) Math.ceil((double) totalSize / numberOfParts);

        for (int i = 0; i < totalSize; i += chunkSize) {
            subLists.add(new ArrayList<>(originalList.subList(i, Math.min(totalSize, i + chunkSize))));
        }

        return subLists;
    }
}
